"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 数据库系统
Case Name   : 归档目录中已有重名文件或软连接存在
Create At   : 2020/07/01
Owner       : @wan005
Description :
    1、修改归档开关及新建归档路径；
    2、切换到一个新的事务日志文件(产生一个新的xlog文件)；
    3、创建归档目录，并在归档路径新建属于ready状态的文件（新建文件名为新产生的xlog文件名）；
    4、插入大量事务；查看文件是否覆盖
Expect      :
    1、修改归档开关及新建归档路径成功
    2、切换到一个新的事务日志文件(产生一个新的xlog文件)成功
    3、创建归档目录，并在归档路径新建属于ready状态的文件（新建文件名为新产生的xlog文件名）成功；
    4、插入大量事务；查看归档路径下文件被覆盖
History     :
    modified: 2021/1/7  modified by @peilinqian,优化参数配置方法，teardown增加恢复参数操作
    modified: 2021/2/4  modified by @peilinqian,优化用例逻辑，增加同步等待
    modified: 2021/2/9  modified by @peilinqian,优化创建归档目录下文件权限失败，历史数据没有清理干净导致
"""
import os
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import *
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class DbsysCase039(unittest.TestCase):
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log = Logger()
        self.log.info('----Opengauss_Reliability_Dbsys_Case039.py start----')
        self.pri_dbuser = Node(node='PrimaryDbUser')
        self.pri_root = Node(node='PrimaryRoot')
        self.arch_path = macro.ARCH_PATH
        self.sh = CommonSH()
        self.com = Common()
        self.constant = Constant()

        self.log.info('----修改归档参数并新建归档路径----')
        ls_result = self.sh.executeGsguc('reload',
                                         self.constant.GSGUC_SUCCESS_MSG,
                                         'archive_mode = on')
        self.assertTrue(ls_result)
        archive_cmd = f"archive_command ='cp --remove-destination" \
            f" %p {self.arch_path}/%f'"
        self.assertTrue(ls_result)
        ls_result = self.sh.executeGsguc('reload',
                                         self.constant.GSGUC_SUCCESS_MSG,
                                         archive_cmd)
        self.assertTrue(ls_result)
        ls_result = self.sh.executeGsguc('reload',
                                         self.constant.GSGUC_SUCCESS_MSG,
                                         'archive_timeout = 60')
        self.assertTrue(ls_result)
        ls_result = self.sh.executeGsguc('reload',
                                         self.constant.GSGUC_SUCCESS_MSG,
                                         'checkpoint_segments = 10')
        self.assertTrue(ls_result)

        self.log.info('----查看主机query，同步是否正常----')
        self.sh.check_location_consistency('primary', 3)

        self.log.info('----查询主备状态----')
        status = self.sh.getDbClusterStatus('status')
        self.assertTrue(status)

    def test_main(self):
        self.log.info('----切换到一个新的事务日志文件----')
        new_xlog_sql = 'select pg_switch_xlog();'
        new_xlog_result = self.sh.executDbSql(new_xlog_sql)
        self.log.info(new_xlog_result)
        xlog_file_sql = 'select pg_xlogfile_name(pg_current_xlog_location());'
        xlog_file_result = self.sh.executDbSql(xlog_file_sql)
        self.log.info(xlog_file_result)
        xlog_file_name = xlog_file_result.splitlines()[2].strip()
        self.log.info(xlog_file_name)
        xlog_file = os.path.join(self.arch_path, xlog_file_name)
        self.log.info(xlog_file)

        self.log.info('----创建归档目录----')
        exits_cmd = f'ls -al {self.arch_path}'
        exits_result = self.pri_root.sh(exits_cmd).result()
        self.log.info(exits_result)
        rm_cmd = f'rm -rf {self.arch_path};'
        self.log.info(rm_cmd)
        rm_result = self.pri_root.sh(rm_cmd).result()
        self.log.info(rm_result)
        mkdir_cmd = f'mkdir {self.arch_path}'
        self.log.info(mkdir_cmd)
        mkdir_result = self.pri_dbuser.sh(mkdir_cmd).result()
        self.log.info(mkdir_result)

        self.log.info('----归档路径新建属于ready状态的文件----')
        touch_cmd = f'touch {xlog_file}'
        self.log.info(touch_cmd)
        touch_result = self.pri_dbuser.sh(touch_cmd).result()
        self.log.info(touch_result)

        du_cmd = f"du -sh {xlog_file}"
        self.log.info(du_cmd)
        du_result = self.pri_dbuser.sh(du_cmd).result()
        self.log.info(du_result)
        file_size = du_result.split()[0]
        self.assertEqual(file_size, '0')

        self.log.info('----插入大量数据，判断归档文件被覆盖----')
        self.com.createLargeNumTable(self.pri_dbuser, 't_test', 1, 100000)
        self.com.createLargeNumTable(self.pri_dbuser, 't_test', 1, 100000)
        self.com.createLargeNumTable(self.pri_dbuser, 't_test', 1, 100000)

        self.log.info('----查看主机query，同步是否正常----')
        self.sh.check_location_consistency('primary', 3)

        du_cmd = f"du -sh {xlog_file}"
        self.log.info(du_cmd)
        du_result = self.pri_dbuser.sh(du_cmd).result()
        self.log.info(du_result)
        file_size = du_result.split()[0]
        self.assertNotEqual(file_size, '0')

        self.log.info('----查询主备状态----')
        status = self.sh.getDbClusterStatus('status')
        self.assertTrue(status)

    def tearDown(self):
        self.log.info('----还原归档开关----')
        self.log.info('----恢复配置参数----')
        self.sh.executeGsguc('reload',
                             self.constant.GSGUC_SUCCESS_MSG,
                             'archive_mode = off')
        self.sh.executeGsguc('reload',
                             self.constant.GSGUC_SUCCESS_MSG,
                             'archive_timeout = 0')
        self.sh.executeGsguc('reload',
                             self.constant.GSGUC_SUCCESS_MSG,
                             'checkpoint_segments = 64')

        self.log.info('----清理环境，删除表----')
        drop_msg = self.com.createLargeNumTable(self.pri_dbuser,
                                                't_test',
                                                del_sign=True)
        self.log.info(drop_msg)

        self.log.info('----清理环境，删除归档路径----')
        exits_cmd = f'ls {self.arch_path}'
        msg = self.pri_root.sh(exits_cmd).result()
        self.log.info(msg)
        if self.constant.NO_FILE_MSG not in msg:
            cmd = f'rm -rf {self.arch_path}'
            self.log.info(cmd)
            msg = self.pri_root.sh(cmd).result()
            if 'Directory not empty' in msg:
                cmd = f'ps ef | grep {self.arch_path}'
                self.log.info(cmd)
                msg = self.pri_root.sh(cmd).result()
                self.log.info(msg)
                pid_list = self.com.parsePidList(msg)
                for pid in pid_list:
                    cmd = f'kill -9 {pid}'
                    self.log.info(cmd)
                    self.pri_root.sh(cmd).result()

                cmd = f'rm -rf {self.arch_path}'
                self.log.info(cmd)
                msg = self.pri_root.sh(cmd).result()
                self.assertEqual(msg, '')

        self.log.info('------reliability_dbsys039 执行完成--------')
